﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace theguineasyndrome
{
    public class MarioModel : CharacterModel
    {
        private Texture2D backEarTexture;
        private Texture2D frontEarTexture;

        private Vector2 backEarIdlingPositionRight;
        private Vector2 backEarIdlingPositionLeft;

        private Vector2 frontEarIdlingPositionRight;
        private Vector2 frontEarIdlingPositionLeft;

        private Vector2 backEarRunningPositionRight;
        private Vector2 backEarRunningPositionLeft;

        private Vector2 frontEarRunningPositionRight;
        private Vector2 frontEarRunningPositionLeft;

        private Vector2 backEarOriginRight;
        private Vector2 backEarOriginLeft;

        private Vector2 frontEarOriginRight;
        private Vector2 frontEarOriginLeft;

        private float backEarRotation;
        private float frontEarRotation;

        private Vector2 shoulderRunningPositionRight;
        private Vector2 shoulderRunningPositionLeft;

        private Vector2 shoulderIdlingPositionRight;
        private Vector2 shoulderIdlingPositionLeft;

        private Texture2D canonTexture;

        private Vector2 canonOriginRight;
        private Vector2 canonOriginLeft;

        private float[] runningOffsets;

        public MarioModel(ContentManager content, Weapon weapon)
            : base(content, weapon)
        {
            animation = new Animation(content.Load<Texture2D>("images/characters/mario/sprite"), new Vector2(87, 150), 60, true);
            animation.setOrigin(new Vector2(43.5f, 140));

            backEarTexture = content.Load<Texture2D>("images/characters/rabbit/backear");
            frontEarTexture = content.Load<Texture2D>("images/characters/rabbit/frontear");

            backEarIdlingPositionRight = new Vector2(-3, -112);
            backEarIdlingPositionLeft = new Vector2(-backEarIdlingPositionRight.X, backEarIdlingPositionRight.Y);

            frontEarIdlingPositionRight = new Vector2(-8, -98);
            frontEarIdlingPositionLeft = new Vector2(-frontEarIdlingPositionRight.X, frontEarIdlingPositionRight.Y);

            backEarRunningPositionRight = new Vector2(13, -107);
            backEarRunningPositionLeft = new Vector2(-backEarRunningPositionRight.X, backEarRunningPositionRight.Y);

            frontEarRunningPositionRight = new Vector2(10, -93);
            frontEarRunningPositionLeft = new Vector2(-frontEarRunningPositionRight.X, frontEarRunningPositionRight.Y);

            backEarOriginRight = new Vector2(33, 64);
            backEarOriginLeft = new Vector2(backEarTexture.Width - backEarOriginRight.X, backEarOriginRight.Y);

            frontEarOriginRight = new Vector2(65, 54);
            frontEarOriginLeft = new Vector2(frontEarTexture.Width - frontEarOriginRight.X, frontEarOriginRight.Y);

            shoulderRunningPositionRight = new Vector2(-8, -80);
            shoulderRunningPositionLeft = new Vector2(-shoulderRunningPositionRight.X, shoulderRunningPositionRight.Y);

            shoulderIdlingPositionRight = new Vector2(-27, -80);
            shoulderIdlingPositionLeft = new Vector2(-shoulderIdlingPositionRight.X, shoulderIdlingPositionRight.Y);

            canonTexture = content.Load<Texture2D>("images/characters/mario/canon");

            canonOriginRight = new Vector2(13.5f, 13.5f);
            canonOriginLeft = new Vector2(canonTexture.Width - canonOriginRight.X, canonOriginRight.Y);

            runningOffsets = new float[] { 0, -1, -5, -3, -1, -1, -5, -4 };

            size = new Vector2(45, 105);
            weight = 0.03f;
            speed = 5.0f;
            jumpForce = 13;
            deceleration = 0.35f;

            calculateMaxSpeed();
        }

        public override Vector2 getShoulderPosition()
        {
            Vector2 shoulderPosition;
            if (animation.xFliped)
            {
                if (character.CurrentState == Character.State.IDLE)
                    shoulderPosition = shoulderIdlingPositionLeft;

                else
                    shoulderPosition = shoulderRunningPositionLeft;
            }
            else
            {
                if (character.CurrentState == Character.State.IDLE)
                    shoulderPosition = shoulderIdlingPositionRight;

                else
                    shoulderPosition = shoulderRunningPositionRight;
            }
            return shoulderPosition;
        }

        public override Vector2 getFireSource()
        {
            Vector2 canonSize = new Vector2(15, 0);
            if (animation.xFliped)
                canonSize.Y *= -1;

            float armAngle = character.ArmAngle;
            Vector2 fireSource = getShoulderPosition() + new Vector2((float)(-Math.Sin(armAngle) * canonSize.Y + Math.Cos(armAngle) * canonSize.X), (float)(Math.Cos(armAngle) * canonSize.Y + Math.Sin(armAngle) * canonSize.X));

            return fireSource;
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            backEarRotation = (float)Math.Cos(gameTime.TotalGameTime.TotalMilliseconds / 500) / 20;
            frontEarRotation = (float)Math.Sin(gameTime.TotalGameTime.TotalMilliseconds / 400) / 15;
        }

        public override void Draw(SpriteBatch spriteBatch, Camera camera)
        {
            SpriteEffects effects = SpriteEffects.None;
            Vector2 backEarPosition;
            Vector2 frontEarPosition;
            Vector2 backEarOrigin;
            Vector2 frontEarOrigin;
            Vector2 canonOrigin;
            float canonAngle;
            Vector2 shoulderPosition;

            if (animation.xFliped)
            {
                effects |= SpriteEffects.FlipHorizontally;
                backEarOrigin = backEarOriginLeft;
                frontEarOrigin = frontEarOriginLeft;
                canonAngle = (float)(character.ArmAngle + Math.PI);
                canonOrigin = canonOriginLeft;

                if (character.CurrentState == Character.State.IDLE)
                {
                    backEarPosition = backEarIdlingPositionLeft;
                    frontEarPosition = frontEarIdlingPositionLeft;
                    shoulderPosition = shoulderIdlingPositionLeft;
                }
                else
                {
                    backEarPosition = backEarRunningPositionLeft;
                    frontEarPosition = frontEarRunningPositionLeft;
                    shoulderPosition = shoulderRunningPositionLeft;
                }
            }
            else
            {
                backEarOrigin = backEarOriginRight;
                frontEarOrigin = frontEarOriginRight;
                canonAngle = character.ArmAngle;
                canonOrigin = canonOriginRight;

                if (character.CurrentState == Character.State.IDLE)
                {
                    backEarPosition = backEarIdlingPositionRight;
                    frontEarPosition = frontEarIdlingPositionRight;
                    shoulderPosition = shoulderIdlingPositionRight;
                }
                else
                {
                    backEarPosition = backEarRunningPositionRight;
                    frontEarPosition = frontEarRunningPositionRight;
                    shoulderPosition = shoulderRunningPositionRight;
                }
            }

            if (character.CurrentState == Character.State.RUN)
            {
                Vector2 offset = new Vector2(0, runningOffsets[animation.CurrentFrame]);
                backEarPosition += offset;
                frontEarPosition += offset;
                shoulderPosition += offset;
            }

            spriteBatch.Draw(backEarTexture, camera.getDstPoint(animation.Position + backEarPosition), null, Color.White, backEarRotation, backEarOrigin, 1, effects, 0);
            base.Draw(spriteBatch, camera);
            spriteBatch.Draw(frontEarTexture, camera.getDstPoint(animation.Position + frontEarPosition), null, Color.White, frontEarRotation, frontEarOrigin, 1, effects, 0);
            spriteBatch.Draw(canonTexture, camera.getDstPoint(animation.Position + shoulderPosition), null, Color.White, canonAngle, canonOrigin, 1, effects, 0);
        }
    }
}
